home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-05-13 | 48.9 KB | 2,273 lines |
- Newsgroups: comp.sources.misc
- From: pfalstad@phoenix.Princeton.EDU (Paul Falstad)
- Subject: v29i103: zsh2.2 - The Z shell, Part07/17
- Message-ID: <1992May13.160014.9065@sparky.imd.sterling.com>
- X-Md4-Signature: d4b7284ef1c152a41bdd8bc679dafb7e
- Date: Wed, 13 May 1992 16:00:14 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: pfalstad@phoenix.Princeton.EDU (Paul Falstad)
- Posting-number: Volume 29, Issue 103
- Archive-name: zsh2.2/part07
- Environment: BSD
- Supersedes: zsh2.1: Volume 24, Issue 1-19
-
- #!/bin/sh
- # this is aa.07 (part 7 of zsh2.2)
- # do not concatenate these parts, unpack them in order with /bin/sh
- # file zsh2.2/src/builtin.c continued
- #
- if test ! -r _shar_seq_.tmp; then
- echo 'Please unpack part 1 first!'
- exit 1
- fi
- (read Scheck
- if test "$Scheck" != 7; then
- echo Please unpack part "$Scheck" next!
- exit 1
- else
- exit 0
- fi
- ) < _shar_seq_.tmp || exit 1
- if test ! -f _shar_wnt_.tmp; then
- echo 'x - still skipping zsh2.2/src/builtin.c'
- else
- echo 'x - continuing file zsh2.2/src/builtin.c'
- sed 's/^X//' << 'SHAR_EOF' >> 'zsh2.2/src/builtin.c' &&
- X if (flags & BINF_ECHOPTS && arg && strcmp(arg,"-n"))
- X optstr = NULL;
- X if (optstr)
- X while (arg &&
- X ((sense = *arg == '-') || fset(BINF_PLUSOPTS) && *arg == '+') &&
- X (fset(BINF_PLUSOPTS) || !atoi(arg)))
- X {
- X pp = arg;
- X if (arg[1] == '-')
- X arg++;
- X if (!arg[1])
- X {
- X ops['-'] = 1;
- X if (!sense)
- X ops['+'] = 1;
- X }
- X else
- X ops['@'] = 1;
- X op = -1;
- X while (*++arg)
- X if (strchr(b->optstr,op = *arg))
- X ops[*arg] = (sense) ? 1 : 2;
- X else
- X break;
- X if (*arg)
- X {
- X zerr("bad option: %c",NULL,*arg);
- X return 1;
- X }
- X arg = ugetnode(args);
- X if (fset(BINF_SETOPTS) && op == 'o')
- X {
- X int c;
- X
- X if (!arg)
- X prtopt();
- X else
- X {
- X c = optlookup(arg);
- X if (c == -1)
- X {
- X zerr("bad option: %s",arg,0);
- X return 1;
- X }
- X else
- X {
- X ops[c] = ops['o'];
- X arg = ugetnode(args);
- X }
- X }
- X }
- X if ((fset(BINF_PRINTOPTS) && ops['R']) || ops['-'])
- X break;
- X if (fset(BINF_SETOPTS) && ops['A'])
- X {
- X auxdata = arg;
- X arg = ugetnode(args);
- X break;
- X }
- X if (fset(BINF_FCOPTS) && op == 'e')
- X {
- X auxdata = arg;
- X arg = ugetnode(args);
- X }
- X if (fset(BINF_TYPEOPT) && (op == 'L' || op == 'R' ||
- X op == 'Z' || op == 'i') && arg && idigit(*arg))
- X {
- X auxlen = atoi(arg);
- X arg = ugetnode(args);
- X }
- X }
- X if (fset(BINF_R))
- X auxdata = "-";
- X if (pp = b->defopts)
- X while (*pp)
- X ops[*pp++] = 1;
- X if (arg)
- X {
- X argc = 1;
- X n = firstnode(args);
- X while (n)
- X argc++,incnode(n);
- X }
- X oargv = argv = (char **) ncalloc(sizeof(char **) * (argc+1));
- X if (*argv++ = arg)
- X while (*argv++ = ugetnode(args));
- X argv = oargv;
- X if (errflag)
- X return 1;
- X if (argc < b->minargs || (argc > b->maxargs && b->maxargs != -1)) {
- X zerrnam(name,(argc < b->minargs)
- X ? "not enough arguments" : "too many arguments",NULL,0);
- X return 1;
- X }
- X if (isset(XTRACE)) {
- X char **pp = argv;
- X fprintf(stderr,"%s%s",(prompt4) ? prompt4 : "",name);
- X while (*pp) fprintf(stderr," %s",*pp++);
- X fputc('\n',stderr);
- X fflush(stderr);
- X }
- X return (*(b->handlerfunc))(name,argv,ops,b->funcid);
- X}
- X
- Xstruct asgment *getasg(s) /**/
- Xchar *s;
- X{
- Xstatic struct asgment asg;
- X
- X if (!s)
- X return NULL;
- X if (*s == '=')
- X {
- X zerr("bad assignment",NULL,0);
- X return NULL;
- X }
- X asg.name = s;
- X for (; *s && *s != '='; s++);
- X if (*s)
- X {
- X *s = '\0';
- X asg.value = s+1;
- X }
- X else
- X asg.value = NULL;
- X return &asg;
- X}
- X
- X/* ., source */
- X
- Xint bin_dot(name,argv,ops,func) /**/
- Xchar *name;char **argv;char *ops;int func;
- X{
- Xchar **old,*old0;
- Xint ret;
- Xchar buf[MAXPATHLEN];
- Xchar *s,**t,*enam;
- X
- X if (!*argv)
- X return 0;
- X old = pparams;
- X old0 = argzero;
- X if (argv[1]) {
- X permalloc();
- X pparams = arrdup(argv+1);
- X heapalloc();
- X }
- X enam = argzero = ztrdup(*argv);
- X errno = ENOENT;
- X ret = 1;
- X for (s = argzero; *s; s++)
- X if (*s == '/') {
- X ret = source(argzero);
- X break;
- X }
- X if (!*s) {
- X for (t = path; *t; t++)
- X if ((*t)[0] == '.' && !(*t)[1]) {
- X ret = source(argzero);
- X break;
- X } else {
- X sprintf(buf,"%s/%s",*t,argzero);
- X if (access(buf,F_OK) == 0) {
- X ret = source(enam = buf);
- X break;
- X }
- X }
- X if (!*t && access(argzero,F_OK) == 0)
- X ret = source(enam = argzero);
- X }
- X if (argv[1]) {
- X freearray(pparams);
- X pparams = old;
- X }
- X if (ret) zerrnam(name,"%e: %s",enam,errno);
- X free(argzero);
- X argzero = old0;
- X return ret;
- X}
- X
- Xint bin_set(name,argv,ops,func) /**/
- Xchar *name;char **argv;char *ops;int func;
- X{
- Xstruct option *opp;
- Xchar **x;
- X
- X if (((ops['+'] && ops['-']) || !ops['-']) && !ops['@'] && !*argv)
- X {
- X showflag = ~0;
- X showflag2 = ops['+'];
- X listhtable(paramtab,(HFunc) printparam);
- X }
- X for (opp = optns; opp->name; opp++)
- X if (ops[opp->id] == 1)
- X opts[opp->id] = OPT_SET;
- X else if (ops[opp->id] == 2)
- X opts[opp->id] = OPT_UNSET;
- X if (!*argv && !ops['-'])
- X return 0;
- X permalloc();
- X x = arrdup(argv);
- X heapalloc();
- X if (ops['A'])
- X setaparam(auxdata,x);
- X else {
- X freearray(pparams);
- X pparams = x;
- X }
- X return 0;
- X}
- X
- X#define pttime(X) printf("%dm%ds",(X)/3600,(X)/60%60)
- X
- Xint bin_times(name,argv,ops,func) /**/
- Xchar *name;char **argv;char *ops;int func;
- X{
- Xstruct tms buf;
- X
- X if (times(&buf) == -1)
- X return 1;
- X pttime(buf.tms_utime);
- X putchar(' ');
- X pttime(buf.tms_stime);
- X putchar('\n');
- X pttime(buf.tms_cutime);
- X putchar(' ');
- X pttime(buf.tms_cstime);
- X putchar('\n');
- X return 0;
- X}
- X
- Xint bin_getopts(name,argv,ops,func) /**/
- Xchar *name;char **argv;char *ops;int func;
- X{
- Xchar *optstr = *argv++,*var = *argv++;
- Xchar **args = (*argv) ? argv : pparams;
- Xstatic int optcind = 1,quiet;
- Xchar *str,optbuf[3],*opch = optbuf+1;
- X
- X if (zoptind < 1) zoptind = 1;
- X optbuf[0] = '+'; optbuf[1] = optbuf[2] = '\0';
- X if (optarg) free(optarg);
- X optarg = ztrdup("");
- X setsparam(var,ztrdup(""));
- X if (*optstr == ':') {
- X quiet = 1;
- X optstr++;
- X }
- X if (zoptind > arrlen(args)) return 1;
- X str = args[zoptind-1];
- X if (*str != '+' && *str != '-' || optcind >= strlen(str) ||
- X !strcmp("--",str)) {
- X if (*str == '+' || *str == '-')
- X zoptind++;
- X optcind = 0;
- X return 1;
- X }
- X if (!optcind)
- X optcind = 1;
- X *opch = str[optcind++];
- X if (!args[zoptind-1][optcind]) {
- X zoptind++;
- X optcind = 0;
- X }
- X for (; *optstr; optstr++)
- X if (*opch == *optstr)
- X break;
- X if (!*optstr) {
- X setsparam(var,ztrdup("?"));
- X if (quiet) {
- X free(optarg); optarg = ztrdup(opch);
- X return 0;
- X }
- X zerr("bad option: %c",NULL,*opch); errflag = 0;
- X return 0;
- X }
- X setsparam(var,ztrdup(opch-(*str == '+')));
- X if (optstr[1] == ':') {
- X if (!args[zoptind-1]) {
- X if (quiet) {
- X free(optarg); optarg = ztrdup(opch);
- X setsparam(var,ztrdup(":"));
- X return 0;
- X }
- X setsparam(var,ztrdup("?"));
- X zerr("argument expected after %c option",NULL,*opch); errflag = 0;
- X return 0;
- X }
- X free(optarg);
- X optarg = ztrdup(args[zoptind-1]+optcind);
- X zoptind++;
- X optcind = 0;
- X }
- X return 0;
- X}
- X
- X/* get a signal number from a string */
- X
- Xint getsignum(s) /**/
- Xchar *s;
- X{
- Xint x = atoi(s),t0;
- X
- X if (idigit(*s) && x >= 0 && x < VSIGCOUNT)
- X return x;
- X for (t0 = 0; t0 != VSIGCOUNT; t0++)
- X if (!strcmp(s,sigs[t0]))
- X return t0;
- X return -1;
- X}
- X
- Xint bin_trap(name,argv,ops,func) /**/
- Xchar *name;char **argv;char *ops;int func;
- X{
- XList l;
- Xchar *arg;
- X
- X if (!*argv) {
- X int t0;
- X
- X for (t0 = 0; t0 != VSIGCOUNT; t0++)
- X if (sigtrapped[t0])
- X if (!sigfuncs[t0])
- X printf("TRAP%s () {}\n",sigs[t0]);
- X else {
- X char *s = getpermtext((vptr) sigfuncs[t0]);
- X printf("TRAP%s () {\n\t%s\n}\n",sigs[t0],s);
- X free(s);
- X }
- X return 0;
- X }
- X if (!strcmp(*argv,"-")) {
- X int t0;
- X
- X argv++;
- X if (!*argv)
- X for (t0 = 0; t0 != VSIGCOUNT; t0++) unsettrap(t0);
- X else
- X while (*argv) unsettrap(getsignum(*argv++));
- X return 0;
- X }
- X arg = *argv++;
- X if (!*arg) l = NULL;
- X else if (!(l = parselstring(arg))) {
- X zerrnam(name,"couldn't parse trap command",NULL,0);
- X popheap();
- X return 1;
- X }
- X for (; *argv; argv++) {
- X int sg = getsignum(*argv);
- X if (sg == -1) {
- X zerrnam(name,"undefined signal: %s",*argv,0);
- X break;
- X }
- X settrap(sg,l);
- X }
- X if (l) popheap();
- X return errflag;
- X}
- X
- Xvoid printulimit(lim,hard) /**/
- Xint lim;int hard;
- X{
- Xlong t0;
- X
- X#ifdef RLIM_INFINITY
- X t0 = (hard) ? limits[lim].rlim_max : limits[lim].rlim_cur;
- X switch (lim)
- X {
- X case RLIMIT_CPU: printf("cpu time (seconds) "); break;
- X case RLIMIT_FSIZE: printf("file size (blocks) "); t0 /= 512; break;
- X case RLIMIT_DATA: printf("data seg size (kbytes) "); t0 /= 1024; break;
- X case RLIMIT_STACK: printf("stack size (kbytes) "); t0 /= 1024; break;
- X case RLIMIT_CORE: printf("core file size (blocks) "); t0 /= 512; break;
- X#ifdef RLIMIT_RSS
- X case RLIMIT_RSS: printf("resident set size (kbytes) "); t0 /= 1024; break;
- X#endif
- X#ifdef RLIMIT_NOFILE
- X case RLIMIT_NOFILE: printf("file descriptors "); break;
- X#endif
- X }
- X printf("%ld\n",t0);
- X#endif
- X}
- X
- Xint bin_ulimit(name,argv,ops,func) /**/
- Xchar *name;char **argv;char *ops;int func;
- X{
- Xint res,hard;
- X
- X#ifndef RLIM_INFINITY
- X zerrnam(name,"not available on this system",NULL,0);
- X return 1;
- X#else
- X hard = ops['H'];
- X if (ops['a'] || !ops['@'])
- X res = -1;
- X else if (ops['t'])
- X res = RLIMIT_CPU;
- X else if (ops['f'])
- X res = RLIMIT_FSIZE;
- X else if (ops['d'])
- X res = RLIMIT_DATA;
- X else if (ops['s'])
- X res = RLIMIT_STACK;
- X else if (ops['c'])
- X res = RLIMIT_CORE;
- X#ifdef RLIMIT_RSS
- X else if (ops['m'])
- X res = RLIMIT_RSS;
- X#endif
- X#ifdef RLIMIT_NOFILE
- X else if (ops['n'])
- X res = RLIMIT_NOFILE;
- X#endif
- X else
- X {
- X zerrnam(name,"no such limit",NULL,0);
- X return 1;
- X }
- X if (res == -1)
- X if (*argv)
- X {
- X zerrnam(name,"no arguments required after -a",NULL,0);
- X return 1;
- X }
- X else
- X {
- X int t0;
- X
- X for (t0 = 0; t0 != RLIM_NLIMITS; t0++)
- X printulimit(t0,hard);
- X return 0;
- X }
- X if (!*argv)
- X printulimit(res,hard);
- X else if (strcmp(*argv,"unlimited"))
- X {
- X long t0;
- X
- X t0 = atol(*argv);
- X switch(res)
- X {
- X case RLIMIT_FSIZE: case RLIMIT_CORE: t0 *= 512; break;
- X case RLIMIT_DATA: case RLIMIT_STACK:
- X#ifdef RLIMIT_RSS
- X case RLIMIT_RSS:
- X#endif
- X t0 *= 1024; break;
- X }
- X if (hard)
- X {
- X if (t0 > limits[res].rlim_max && geteuid())
- X {
- X zerrnam(name,"can't raise hard limits",NULL,0);
- X return 1;
- X }
- X limits[res].rlim_max = t0;
- X }
- X else
- X {
- X if (t0 > limits[res].rlim_max)
- X {
- X if (geteuid())
- X {
- X zerrnam(name,"value exceeds hard limit",NULL,0);
- X return 1;
- X }
- X limits[res].rlim_max = limits[res].rlim_cur = t0;
- X }
- X else
- X limits[res].rlim_cur = t0;
- X }
- X }
- X else
- X {
- X if (hard)
- X {
- X if (geteuid())
- X {
- X zerrnam(name,"can't remove hard limits",NULL,0);
- X return 1;
- X }
- X limits[res].rlim_max = RLIM_INFINITY;
- X }
- X else
- X limits[res].rlim_cur = limits[res].rlim_max;
- X }
- X return 0;
- X#endif
- X}
- X
- Xint putraw(c) /**/
- Xint c;
- X{
- X putchar(c);
- X return 0;
- X}
- X
- Xint bin_echotc(name,argv,ops,func) /**/
- Xchar *name;char **argv;char *ops;int func;
- X{
- Xchar *s,buf[2048],*t,*u;
- Xint num,argct,t0;
- X
- X s = *argv++;
- X if (!termok)
- X return 1;
- X if ((num = tgetnum(s)) != -1)
- X {
- X printf("%d\n",num);
- X return 0;
- X }
- X u = buf;
- X t = tgetstr(s,&u);
- X if (!t || !*t)
- X {
- X zerrnam(name,"no such capability: %s",s,0);
- X return 1;
- X }
- X for (argct = 0, u = t; *u; u++)
- X if (*u == '%')
- X {
- X if (u++, (*u == 'd' || *u == '2' || *u == '3' || *u == '.' ||
- X *u == '+'))
- X argct++;
- X }
- X if (arrlen(argv) != argct)
- X {
- X zerrnam(name,(arrlen(argv) < argct) ? "not enough arguments" :
- X "too many arguments",NULL,0);
- X return 1;
- X }
- X if (!argct)
- X tputs(t,1,putraw);
- X else
- X {
- X t0 = (argv[1]) ? atoi(argv[1]) : atoi(*argv);
- X tputs(tgoto(t,atoi(*argv),t0),t0,putraw);
- X }
- X return 0;
- X}
- X
- Xint bin_pwd(name,argv,ops,func) /**/
- Xchar *name;char **argv;char *ops;int func;
- X{
- X printf("%s\n",pwd);
- X return 0;
- X}
- X
- X#define TEST_END 0
- X#define TEST_INPAR 1
- X#define TEST_OUTPAR 2
- X#define TEST_STR 3
- X#define TEST_AND 4
- X#define TEST_OR 5
- X#define TEST_NOT 6
- X
- Xstatic char **tsp;
- Xstatic int *tip;
- X
- Xint bin_test(name,argv,ops,func) /**/
- Xchar *name;char **argv;char *ops;int func;
- X{
- Xchar **s;
- Xint cnt,*arr,*ap;
- XCond c;
- X
- X if (func == BIN_BRACKET)
- X {
- X for (s = argv; *s; s++);
- X if (s == argv || strcmp(s[-1],"]"))
- X {
- X zerrnam(name,"']' expected",NULL,0);
- X return 1;
- X }
- X s[-1] = NULL;
- X }
- X for (s = argv, cnt = 0; *s; s++,cnt++);
- X ap = arr = alloc((cnt+1)*sizeof *arr);
- X for (s = argv; *s; s++,ap++)
- X if (!strcmp(*s,"("))
- X *ap = TEST_INPAR;
- X else if (!strcmp(*s,")"))
- X *ap = TEST_OUTPAR;
- X else if (!strcmp(*s,"-a"))
- X *ap = TEST_AND;
- X else if (!strcmp(*s,"-o"))
- X *ap = TEST_OR;
- X else if (!strcmp(*s,"!"))
- X *ap = TEST_NOT;
- X else
- X *ap = TEST_STR;
- X *ap = TEST_END;
- X tsp = argv;
- X tip = arr;
- X c = partest(0);
- X if (*tip != TEST_END || errflag)
- X {
- X zerrnam(name,"parse error",NULL,0);
- X return 1;
- X }
- X return (c) ? !evalcond(c) : 1;
- X}
- X
- XCond partest(level) /**/
- Xint level;
- X{
- XCond a,b;
- X
- X switch (level)
- X {
- X case 0:
- X a = partest(1);
- X if (*tip == TEST_OR)
- X {
- X tip++,tsp++;
- X b = makecond();
- X b->left = a;
- X b->right = partest(0);
- X b->type = COND_OR;
- X return b;
- X }
- X return a;
- X case 1:
- X a = partest(2);
- X if (*tip == TEST_AND)
- X {
- X tip++,tsp++;
- X b = makecond();
- X b->left = a;
- X b->right = partest(1);
- X b->type = COND_AND;
- X return b;
- X }
- X return a;
- X case 2:
- X if (*tip == TEST_NOT)
- X {
- X tip++,tsp++;
- X b = makecond();
- X b->left = partest(2);
- X b->type = COND_NOT;
- X return b;
- X }
- X case 3:
- X if (*tip == TEST_INPAR)
- X {
- X tip++,tsp++;
- X b = partest(0);
- X if (*tip != TEST_OUTPAR)
- X {
- X zerrnam("test","parse error",NULL,0);
- X return NULL;
- X }
- X tip++,tsp++;
- X return b;
- X }
- X if (tip[0] != TEST_STR)
- X {
- X zerrnam("test","parse error",NULL,0);
- X return NULL;
- X }
- X else if (tip[1] != TEST_STR)
- X {
- X b = makecond();
- X if (!strcmp(*tsp,"-t"))
- X {
- X b->left = strdup("1");
- X b->type = 't';
- X }
- X else
- X {
- X b->left = tsp[0];
- X b->type = 'n';
- X }
- X tip++,tsp++;
- X return b;
- X }
- X else if (tip[2] != TEST_STR)
- X {
- X b = par_cond_double(tsp[0],tsp[1]);
- X tip += 2,tsp += 2;
- X return b;
- X }
- X else
- X {
- X b = par_cond_triple(tsp[0],tsp[1],tsp[2]);
- X tip += 3,tsp += 3;
- X return b;
- X }
- X }
- X return NULL;
- X}
- X
- Xint bin_compctl(name,argv,ops,func) /**/
- Xchar *name;char **argv;char *ops;int func;
- X{
- Xint flags = 0;
- XCompctl cc = NULL;
- Xchar *usrkeys = NULL;
- X
- X for (; *argv && **argv == '-'; argv++)
- X while (*++(*argv)) switch(**argv) {
- X case 'c': flags |= CC_COMMPATH; break;
- X case 'f': flags |= CC_FILES; break;
- X case 'h': flags |= CC_HOSTS; break;
- X case 'o': flags |= CC_OPTIONS; break;
- X case 'v': flags |= CC_VARS; break;
- X case 'b': flags |= CC_BINDINGS; break;
- X case 'k':
- X flags |= CC_USRKEYS;
- X if ((*argv)[1]) { usrkeys = (*argv)+1; *argv = ""-1; }
- X else if (!argv[1]) {
- X zerrnam(name,"variable name expected after -k",NULL,0);
- X return 1;
- X } else { usrkeys = *++argv; *argv = ""-1; }
- X break;
- X case 'C': cc = &cc_compos; break;
- X case 'D': cc = &cc_default; break;
- X default: zerrnam(name,"bad option: %c",NULL,**argv); return 1;
- X }
- X if (cc) {
- X cc->mask = flags;
- X if (cc->keyvar) free(cc->keyvar);
- X cc->keyvar = ztrdup(usrkeys);
- X }
- X if (!*argv) {
- X if (!cc) {
- X showflag = flags;
- X listhtable(compctltab,(HFunc) printcompctl);
- X printcompctl("COMMAND",&cc_compos);
- X printcompctl("DEFAULT",&cc_default);
- X }
- X return 0;
- X }
- X compctl_process(argv,flags,usrkeys);
- X return 0;
- X}
- X
- Xvoid printcompctl(s,cc) /**/
- Xchar *s;Compctl cc;
- X{
- Xchar *css = "fchovb";
- X
- X if (cc->mask & showflag) {
- X puts(s);
- X } else if (!showflag) {
- X int flags = cc->mask;
- X printf("%s -",s);
- X while (*css) {
- X if (flags & 1) putchar(*css);
- X css++; flags >>= 1;
- X }
- X if (flags & 1) printf("k %s",cc->keyvar);
- X putchar('\n');
- X }
- X}
- X
- Xvoid compctl_process(s,mask,uk) /**/
- Xchar **s;int mask;char *uk;
- X{
- XCompctl cc;
- X
- X for (;*s;s++) {
- X cc = zalloc(sizeof *cc);
- X cc->mask = mask; cc->keyvar = ztrdup(uk);
- X addhnode(ztrdup(*s),cc,compctltab,freecompctl);
- X }
- X}
- X
- Xint bin_ttyctl(name,argv,ops,func) /**/
- Xchar *name;char **argv;char *ops;int func;
- X{
- X if (ops['f'] || !ops['@']) ttyfrozen = 1;
- X else if (ops['u']) ttyfrozen = 0;
- X return 0;
- X}
- X
- SHAR_EOF
- echo 'File zsh2.2/src/builtin.c is complete' &&
- chmod 0644 zsh2.2/src/builtin.c ||
- echo 'restore of zsh2.2/src/builtin.c failed'
- Wc_c="`wc -c < 'zsh2.2/src/builtin.c'`"
- test 61945 -eq "$Wc_c" ||
- echo 'zsh2.2/src/builtin.c: original size 61945, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= zsh2.2/src/cond.c ==============
- if test -f 'zsh2.2/src/cond.c' -a X"$1" != X"-c"; then
- echo 'x - skipping zsh2.2/src/cond.c (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting zsh2.2/src/cond.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'zsh2.2/src/cond.c' &&
- X/*
- X *
- X * cond.c - evaluate conditional expressions
- X *
- X * This file is part of zsh, the Z shell.
- X *
- X * This software is Copyright 1992 by Paul Falstad
- X *
- X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
- X * use this software as long as: there is no monetary profit gained
- X * specifically from the use or reproduction of this software, it is not
- X * sold, rented, traded or otherwise marketed, and this copyright notice is
- X * included prominently in any copy made.
- X *
- X * The author make no claims as to the fitness or correctness of this software
- X * for any use whatsoever, and it is provided as is. Any use of this software
- X * is at the user's own risk.
- X *
- X */
- X
- X#include "zsh.h"
- X
- Xint evalcond(c) /**/
- XCond c;
- X{
- Xstruct stat *st;
- X
- X switch (c->type)
- X {
- X case COND_NOT: return !evalcond(c->left);
- X case COND_AND: return evalcond(c->left) && evalcond(c->right);
- X case COND_OR: return evalcond(c->left) || evalcond(c->right);
- X }
- X singsub((char **) &c->left);
- X untokenize(c->left);
- X if (c->right)
- X {
- X singsub((char **) &c->right);
- X if (c->type != COND_STREQ && c->type != COND_STRNEQ)
- X untokenize(c->right);
- X }
- X switch (c->type)
- X {
- X case COND_STREQ: return matchpat(c->left,c->right);
- X case COND_STRNEQ: return !matchpat(c->left,c->right);
- X case COND_STRLT: return strcmp(c->left,c->right) < 0;
- X case COND_STRGTR: return strcmp(c->left,c->right) > 0;
- X case 'e': case 'a': return(doaccess(c->left,F_OK));
- X case 'b': return(S_ISBLK(dostat(c->left)));
- X case 'c': return(S_ISCHR(dostat(c->left)));
- X case 'd': return(S_ISDIR(dostat(c->left)));
- X case 'f': return(S_ISREG(dostat(c->left)));
- X case 'g': return(!!(dostat(c->left) & S_ISGID));
- X case 'k': return(!!(dostat(c->left) & S_ISVTX));
- X case 'n': return(!!strlen(c->left));
- X case 'o': return(optison(c->left));
- X case 'p': return(S_ISFIFO(dostat(c->left)));
- X case 'r': return(doaccess(c->left,R_OK));
- X case 's': return((st = getstat(c->left)) && !!(st->st_size));
- X case 'S': return(S_ISSOCK(dostat(c->left)));
- X case 'u': return(!!(dostat(c->left) & S_ISUID));
- X case 'w': return(doaccess(c->left,W_OK));
- X case 'x': return(doaccess(c->left,X_OK));
- X case 'z': return(!strlen(c->left));
- X case 'h': case 'L': return(S_ISLNK(dolstat(c->left)));
- X case 'O': return((st = getstat(c->left)) && st->st_uid == geteuid());
- X case 'G': return((st = getstat(c->left)) && st->st_gid == getegid());
- X case 't': return isatty(matheval(c->left));
- X case COND_EQ: return matheval(c->left) == matheval(c->right);
- X case COND_NE: return matheval(c->left) != matheval(c->right);
- X case COND_LT: return matheval(c->left) < matheval(c->right);
- X case COND_GT: return matheval(c->left) > matheval(c->right);
- X case COND_LE: return matheval(c->left) <= matheval(c->right);
- X case COND_GE: return matheval(c->left) >= matheval(c->right);
- X case COND_NT: case COND_OT:
- X {
- X time_t a;
- X if (!(st = getstat(c->left)))
- X return 0;
- X a = st->st_mtime;
- X if (!(st = getstat(c->right)))
- X return 0;
- X return (c->type == COND_NT) ? a > st->st_mtime : a < st->st_mtime;
- X }
- X case COND_EF:
- X {
- X dev_t d;
- X ino_t i;
- X
- X if (!(st = getstat(c->left)))
- X return 0;
- X d = st->st_dev;
- X i = st->st_ino;
- X if (!(st = getstat(c->right)))
- X return 0;
- X return d == st->st_dev && i == st->st_ino;
- X }
- X default: zerr("bad cond structure",NULL,0);
- X }
- X return 0;
- X}
- X
- Xint doaccess(s,c) /**/
- Xchar *s;int c;
- X{
- X return !access(s,c);
- X}
- X
- Xstatic struct stat st;
- X
- Xstruct stat *getstat(s) /**/
- Xchar *s;
- X{
- X if (!strncmp(s,"/dev/fd/",8))
- X {
- X if (fstat(atoi(s+8),&st))
- X return NULL;
- X }
- X else if (stat(s,&st))
- X return NULL;
- X return &st;
- X}
- X
- Xunsigned short dostat(s) /**/
- Xchar *s;
- X{
- Xstruct stat *st;
- X
- X if (!(st = getstat(s)))
- X return 0;
- X return st->st_mode;
- X}
- X
- X/* pem@aaii.oz; needed since dostat now uses "stat" */
- X
- Xunsigned short dolstat(s) /**/
- Xchar *s;
- X{
- X if (lstat(s, &st) < 0)
- X return 0;
- X return st.st_mode;
- X}
- X
- Xint optison(s) /**/
- Xchar *s;
- X{
- Xint i;
- X
- X if (strlen(s) == 1)
- X return opts[*s];
- X if ((i = optlookup(s)) != -1)
- X return opts[i];
- X zerr("no such option: %s",s,0);
- X return 0;
- X}
- X
- SHAR_EOF
- chmod 0644 zsh2.2/src/cond.c ||
- echo 'restore of zsh2.2/src/cond.c failed'
- Wc_c="`wc -c < 'zsh2.2/src/cond.c'`"
- test 4064 -eq "$Wc_c" ||
- echo 'zsh2.2/src/cond.c: original size 4064, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= zsh2.2/src/exec.c ==============
- if test -f 'zsh2.2/src/exec.c' -a X"$1" != X"-c"; then
- echo 'x - skipping zsh2.2/src/exec.c (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting zsh2.2/src/exec.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'zsh2.2/src/exec.c' &&
- X/*
- X *
- X * exec.c - command execution
- X *
- X * This file is part of zsh, the Z shell.
- X *
- X * This software is Copyright 1992 by Paul Falstad
- X *
- X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
- X * use this software as long as: there is no monetary profit gained
- X * specifically from the use or reproduction of this software, it is not
- X * sold, rented, traded or otherwise marketed, and this copyright notice is
- X * included prominently in any copy made.
- X *
- X * The author make no claims as to the fitness or correctness of this software
- X * for any use whatsoever, and it is provided as is. Any use of this software
- X * is at the user's own risk.
- X *
- X */
- X
- X#include "zsh.h"
- X#include <sys/errno.h>
- X#ifdef __hpux
- X#include <ndir.h>
- X#else
- X#include <sys/dir.h>
- X#endif
- X
- X#define execerr() { if (forked) exit(1); \
- X closemnodes(mfds); errflag = 1; return; }
- X
- Xstatic Lklist args;
- Xstatic Cmdnam cn;
- X
- X/* parse list in a string */
- X
- XList parselstring(s) /**/
- Xchar *s;
- X{
- XList l;
- X
- X hungets(s);
- X strinbeg();
- X pushheap();
- X if (!(l = parse_list())) {
- X strinend();
- X hflush();
- X popheap();
- X return NULL;
- X }
- X strinend();
- X return l;
- X}
- X
- X/* execute a string */
- X
- Xvoid execstring(s) /**/
- Xchar *s;
- X{
- XList l;
- X
- X if (l = parselstring(s)) {
- X execlist(l);
- X popheap();
- X }
- X}
- X
- X/* fork and set limits */
- X
- Xint phork() /**/
- X{
- Xint pid,t0;
- X
- X if (thisjob >= MAXJOB-1) {
- X zerr("job table full",NULL,0);
- X return -1;
- X }
- X pid = fork();
- X if (pid == -1) {
- X zerr("fork failed: %e",NULL,errno);
- X return -1;
- X }
- X#ifdef RLIM_INFINITY
- X if (!pid)
- X for (t0 = 0; t0 != RLIM_NLIMITS; t0++)
- X setrlimit(t0,limits+t0);
- X#endif
- X return pid;
- X}
- X
- X/* execute a current shell command */
- X
- Xint execcursh(cmd) /**/
- XCmd cmd;
- X{
- X runlist(cmd->u.list);
- X cmd->u.list = NULL;
- X return lastval;
- X}
- X
- X/* execve after handling $_ and #! */
- X
- X#define POUNDBANGLIMIT 64
- X
- Xint zexecve(pth,argv) /**/
- Xchar *pth;char **argv;
- X{
- Xint eno;
- Xstatic char buf[MAXPATHLEN*2];
- Xchar **eep;
- X
- X for (eep = environ; *eep; eep++)
- X if (**eep == '_' && (*eep)[1] == '=') break;
- X buf[0] = '_';
- X buf[1] = '=';
- X if (*pth == '/') strcpy(buf+2,pth);
- X else sprintf(buf+2,"%s/%s",pwd,pth);
- X if (!*eep) eep[1] = NULL;
- X *eep = buf;
- X execve(pth,argv,environ);
- X if ((eno = errno) == ENOEXEC) {
- X char buf[POUNDBANGLIMIT+1],*ptr,*ptr2,*argv0;
- X int fd,ct,t0;
- X
- X if ((fd = open(pth,O_RDONLY)) >= 0) {
- X argv0 = *argv;
- X *argv = pth;
- X ct = read(fd,buf,POUNDBANGLIMIT);
- X close(fd);
- X if (ct > 0) {
- X if (buf[0] == '#')
- X if (buf[1] == '!') {
- X for (t0 = 0; t0 != ct; t0++)
- X if (buf[t0] == '\n')
- X buf[t0] = '\0';
- X buf[POUNDBANGLIMIT] = '\0';
- X for (ptr = buf+2; *ptr && *ptr == ' '; ptr++);
- X for (ptr2 = ptr; *ptr && *ptr != ' '; ptr++);
- X if (*ptr) {
- X *ptr = '\0';
- X argv[-2] = ptr2;
- X argv[-1] = ptr+1;
- X execve(ptr2,argv-2,environ);
- X } else {
- X argv[-1] = ptr2;
- X execve(ptr2,argv-1,environ);
- X }
- X } else {
- X argv[-1] = "sh";
- X execve("/bin/sh",argv-1,environ);
- X }
- X else {
- X for (t0 = 0; t0 != ct; t0++)
- X if (!buf[t0]) break;
- X if (t0 == ct) {
- X argv[-1] = "sh";
- X execve("/bin/sh",argv-1,environ);
- X }
- X }
- X } else eno = errno;
- X *argv = argv0;
- X } else eno = errno;
- X }
- X return eno;
- X}
- X
- X#define MAXCMDLEN (MAXPATHLEN*4)
- X
- X/* execute an external command */
- X
- Xvoid execute(dash) /**/
- Xint dash;
- X{
- Xchar **argv,*arg0,**pp;
- Xchar *z,*s,buf[MAXCMDLEN],buf2[MAXCMDLEN];
- Xint ee = 0,eno = 0;
- X
- X if (!full(args)) {
- X zerr("no command",NULL,0);
- X _exit(1);
- X }
- X cn = (Cmdnam) gethnode(peekfirst(args),cmdnamtab);
- X if (cn && cn->type == DISABLED)
- X cn = NULL;
- X if (s = zgetenv("STTY"))
- X zyztem("stty",s);
- X arg0 = peekfirst(args);
- X if (z = zgetenv("ARGV0")) {
- X setdata(firstnode(args),ztrdup(z));
- X delenv(z-6);
- X } else if (dash) {
- X sprintf(buf2,"-%s",arg0);
- X setdata(firstnode(args),ztrdup(buf2));
- X }
- X argv = makecline(args);
- X fixsigs();
- X if (strlen(arg0) > MAXPATHLEN) {
- X zerr("command too long: %s",arg0,0);
- X _exit(1);
- X }
- X for (s = arg0; *s; s++)
- X if (*s == '/') {
- X errno = zexecve(arg0,argv);
- X if (arg0 == s || unset(PATHDIRS)) {
- X zerr("%e: %s",arg0,errno);
- X _exit(1);
- X }
- X break;
- X }
- X if (cn && ISEXCMD(cn->type)) {
- X for (pp = path; pp < cn->pcomp; pp++)
- X if (**pp == '.' && (*pp)[1] == '\0') {
- X ee = zexecve(arg0,argv);
- X if (ee != ENOENT) eno = ee;
- X } else if (**pp != '/') {
- X z = buf;
- X strucpy(&z,*pp);
- X *z++ = '/';
- X strcpy(z,arg0);
- X ee = zexecve(buf,argv);
- X if (ee != ENOENT) eno = ee;
- X }
- X ee = zexecve(cn->u.nam,argv);
- X if (ee != ENOENT) eno = ee;
- X }
- X for (pp = path; *pp; pp++)
- X if ((*pp)[0] == '.' && !(*pp)[1]) {
- X ee = zexecve(arg0,argv);
- X if (ee != ENOENT) eno = ee;
- X } else {
- X z = buf;
- X strucpy(&z,*pp);
- X *z++ = '/';
- X strcpy(z,arg0);
- X ee = zexecve(buf,argv);
- X if (ee != ENOENT) eno = ee;
- X }
- X if (eno) zerr("%e: %s",arg0,eno);
- X else zerr("command not found: %s",arg0,0);
- X _exit(1);
- X}
- X
- X#define try(X) { if (iscom(X)) return ztrdup(X); }
- X
- X/* get the full pathname of an external command */
- X
- Xchar *findcmd(arg0) /**/
- Xchar *arg0;
- X{
- Xchar **pp;
- Xchar *z,*s,buf[MAXCMDLEN];
- X
- X cn = (Cmdnam) gethnode(arg0,cmdnamtab);
- X if (!cn && isset(HASHCMDS)) hashcmd(arg0,path);
- X if (cn && cn->type == DISABLED) cn = NULL;
- X if (strlen(arg0) > MAXPATHLEN) return NULL;
- X for (s = arg0; *s; s++)
- X if (*s == '/') {
- X try(arg0);
- X if (arg0 == s || unset(PATHDIRS)) {
- X return NULL;
- X }
- X break;
- X }
- X if (cn && ISEXCMD(cn->type)) {
- X for (pp = path; pp < cn->pcomp; pp++)
- X if (**pp != '/') {
- X z = buf;
- X strucpy(&z,*pp);
- X *z++ = '/';
- X strcpy(z,arg0);
- X try(buf);
- X }
- X try(cn->u.nam);
- X }
- X for (pp = path; *pp; pp++) {
- X z = buf;
- X strucpy(&z,*pp);
- X *z++ = '/';
- X strcpy(z,arg0);
- X try(buf);
- X }
- X return NULL;
- X}
- X
- Xint iscom(s) /**/
- Xchar *s;
- X{
- Xstruct stat statbuf;
- X
- X return (access(s,X_OK) == 0 && stat(s,&statbuf) >= 0 &&
- X S_ISREG(statbuf.st_mode));
- X}
- X
- Xint isrelative(s) /**/
- Xchar *s;
- X{
- X if (*s != '/') return 1;
- X for (; *s; s++)
- X if (*s == '.' && s[-1] == '/' &&
- X (s[1] == '/' || s[1] == '\0' ||
- X (s[1] == '.' && (s[2] == '/' || s[2] == '\0')))) return 1;
- X return 0;
- X}
- X
- Xint hashcmd(arg0,pp) /**/
- Xchar *arg0;char **pp;
- X{
- Xchar *s,buf[MAXPATHLEN];
- Xchar **pq;
- XDIR *dir;
- Xstruct direct *de;
- X
- X for (; *pp; pp++)
- X if (**pp == '/') {
- X s = buf;
- X strucpy(&s,*pp);
- X *s++ = '/';
- X strcpy(s,arg0);
- X if (iscom(buf)) break;
- X }
- X if (!*pp || isrelative(*pp)) return 0;
- X cn = (Cmdnam) zcalloc(sizeof *cn);
- X cn->type = EXCMD;
- X cn->pcomp = pp;
- X cn->u.nam = ztrdup(buf);
- X addhnode(ztrdup(arg0),cn,cmdnamtab,freecmdnam);
- X if (unset(HASHDIRS)) return 1;
- X for (pq = pathchecked; pq <= pp; pq++) {
- X if (isrelative(*pq) || !(dir = opendir(*pq))) continue;
- X readdir(dir); readdir(dir);
- X while (de = readdir(dir)) addhcmdnode(de->d_name,pq);
- X closedir(dir);
- X }
- X pathchecked = pp+1;
- X return 1;
- X}
- X
- Xvoid fullhash() /**/
- X{
- Xchar **pq;
- XDIR *dir;
- Xstruct direct *de;
- X
- X for (pq = pathchecked; *pq; pq++) {
- X if (isrelative(*pq) || !(dir = opendir(*pq))) continue;
- X readdir(dir); readdir(dir);
- X while (de = readdir(dir)) addhcmdnode(de->d_name,pq);
- X closedir(dir);
- X }
- X pathchecked = pq;
- X}
- X
- Xvoid execlist(list) /**/
- XList list;
- X{
- X if (breaks) return;
- X if (!list) return;
- X simplifyright(list);
- X switch(list->type) {
- X case SYNC:
- X case ASYNC:
- X execlist2(list->left,list->type,!list->right);
- X if (sigtrapped[SIGDEBUG])
- X dotrap(SIGDEBUG);
- X if (sigtrapped[SIGERR] && lastval)
- X dotrap(SIGERR);
- X if (list->right && !retflag)
- X execlist(list->right);
- X break;
- X }
- X}
- X
- Xvoid execlist2(list,type,last1) /**/
- XSublist list;int type;int last1;
- X{
- X if (!list) return;
- X switch(list->type) {
- X case END:
- X execpline(list,type,last1);
- X break;
- X case ORNEXT:
- X if (!execpline(list,SYNC,0)) execlist2(list->right,type,last1);
- X else while (list = list->right)
- X if (list->type == ANDNEXT) {
- X execlist2(list->right,type,last1);
- X return;
- X }
- X break;
- X case ANDNEXT:
- X if (execpline(list,SYNC,0)) execlist2(list->right,type,last1);
- X else while (list = list->right)
- X if (list->type == ORNEXT) {
- X execlist2(list->right,type,last1);
- X return;
- X }
- X break;
- X }
- X}
- X
- Xint execpline(l,how,last1) /**/
- XSublist l;int how;int last1;
- X{
- Xint ipipe[2],opipe[2];
- X
- X if (!l) return 0;
- X ipipe[0] = ipipe[1] = opipe[0] = opipe[1] = 0;
- X blockchld();
- X if ((thisjob = getfreejob()) == -1)
- X return 1;
- X initjob();
- X if (how == TIMED) {
- X jobtab[thisjob].stat |= STAT_TIMED;
- X how = SYNC;
- X }
- X if (l->flags & PFLAG_COPROC) {
- X how = ASYNC;
- X if (coprocin >= 0) {
- X close(coprocin);
- X close(coprocout);
- X }
- X mpipe(ipipe);
- X mpipe(opipe);
- X coprocin = ipipe[0];
- X coprocout = opipe[1];
- X }
- X execpline2(l->left,how,opipe[0],ipipe[1],last1);
- X if (how == ASYNC) {
- X if (l->flags & PFLAG_COPROC) close(ipipe[1]);
- X spawnjob();
- X unblockchld();
- X return 1;
- X } else {
- X waitjobs();
- X unblockchld();
- X if (l->flags & PFLAG_NOT) lastval = !lastval;
- X return !lastval;
- X }
- X}
- X
- Xvoid execpline2(pline,how,input,output,last1) /**/
- XPline pline;int how;int input;int output;int last1;
- X{
- Xint pid;
- Xint pipes[2];
- X
- X if (breaks)
- X return;
- X if (!pline)
- X return;
- X if (pline->type == END) {
- X execcmd(pline->left,input,output,how==ASYNC,last1);
- X pline->left = NULL;
- X } else {
- X mpipe(pipes);
- X if (pline->left->type >= CURSH && how == SYNC) {
- X
- X /* if we are doing "foo | bar" where foo is a current
- X shell command, do foo in a subshell and do
- X the rest of the pipeline in the current shell. */
- X
- X if (!(pid = fork())) {
- X close(pipes[0]);
- X entersubsh(how==ASYNC);
- X exiting = 1;
- X execcmd(pline->left,input,pipes[1],how==ASYNC,0);
- X _exit(lastval);
- X } else if (pid == -1)
- X zerr("fork failed: %e",NULL,errno);
- X else {
- X char *text = getjobtext((vptr) pline->left);
- X addproc(pid,text);
- X }
- X } else {
- X /* otherwise just do the pipeline normally. */
- X execcmd(pline->left,input,pipes[1],how==ASYNC,0);
- X }
- X pline->left = NULL;
- X close(pipes[1]);
- X if (pline->right) {
- X execpline2(pline->right,how,pipes[0],output,last1);
- X close(pipes[0]);
- X }
- X }
- X}
- X
- X/* make the argv array */
- X
- Xchar **makecline(list) /**/
- Xstruct lklist *list;
- X{
- Xint ct = 0;
- XLknode node;
- Xchar **argv,**ptr;
- X
- X if (isset(XTRACE)) {
- X fprintf(stderr,"%s",(prompt4) ? prompt4 : "");
- X for (node = firstnode(list); node; incnode(node),ct++);
- X ptr = argv = 2+(char **) ncalloc((ct+4)*sizeof(char *));
- X for (node = firstnode(list); node; incnode(node))
- X if (*(char *) getdata(node)) {
- X *ptr++ = getdata(node);
- X untokenize(getdata(node));
- X fputs(getdata(node),stderr);
- X if (nextnode(node))
- X fputc(' ',stderr);
- X }
- X *ptr = NULL;
- X fputc('\n',stderr);
- X fflush(stderr);
- X return(argv);
- X } else {
- X for (node = firstnode(list); node; incnode(node),ct++);
- X ptr = argv = 2+(char **) ncalloc((ct+4)*sizeof(char *));
- X for (node = firstnode(list); node; incnode(node))
- X if (*(char *) getdata(node)) {
- X *ptr++ = getdata(node);
- X untokenize(getdata(node));
- X }
- X *ptr = NULL;
- X return(argv);
- X }
- X}
- X
- X/* untokenize the command line and remove null arguments */
- X
- Xvoid fixcline(l) /**/
- XLklist l;
- X{
- XLknode node,next;
- X
- X for (node = firstnode(l); node; node = next) {
- X next = nextnode(node);
- X if (!*(char *) getdata(node)) uremnode(l,node);
- X else untokenize(getdata(node));
- X }
- X}
- X
- Xvoid untokenize(s) /**/
- Xchar *s;
- X{
- X for (; *s; s++)
- X if (itok(*s))
- X if (*s == Nularg) chuck(s--);
- X else *s = ztokens[*s-Pound];
- X}
- X
- X/* nonzero if we shouldn't clobber a file */
- X
- Xint dontclob(f) /**/
- Xstruct redir *f;
- X{
- Xstruct stat buf;
- X
- X if (unset(NOCLOBBER) || f->type & 1) return 0;
- X if (stat(f->name,&buf) == -1) return 1;
- X return S_ISREG(buf.st_mode);
- X}
- X
- X/* close an multio (success) */
- X
- Xvoid closemn(mfds,fd) /**/
- Xstruct multio **mfds;int fd;
- X{
- X if (mfds[fd]) {
- X if (mfds[fd]->ct > 1)
- X if (mfds[fd]->rflag == 0)
- X catproc(mfds[fd]);
- X else
- X teeproc(mfds[fd]);
- X mfds[fd] = NULL;
- X }
- X}
- X
- X/* close all the mnodes (failure) */
- X
- Xvoid closemnodes(mfds) /**/
- Xstruct multio **mfds;
- X{
- Xint t0,t1;
- X
- X for (t0 = 0; t0 != 10; t0++)
- X if (mfds[t0]) {
- X for (t1 = 0; t1 != mfds[t0]->ct; t1++)
- X close(mfds[t0]->fds[t1]);
- X mfds[t0] = NULL;
- X }
- X}
- X
- X/* add a fd to an multio */
- X/* an multio is a list of fds associated with a certain fd.
- X thus if you do "foo >bar >ble", the multio for fd 1 will have
- X two fds, the result of open("bar",...), and the result of
- X open("ble",....). */
- X
- Xvoid addfd(forked,save,mfds,fd1,fd2,rflag) /**/
- Xint forked;int *save;struct multio **mfds;int fd1;int fd2;int rflag;
- X{
- Xint pipes[2];
- X
- X if (!mfds[fd1]) { /* starting a new multio */
- X mfds[fd1] = (struct multio *) alloc(sizeof(struct multio));
- X if (!forked && fd1 != fd2 && fd1 < 10)
- X save[fd1] = movefd(fd1);
- X redup(fd2,fd1);
- X mfds[fd1]->ct = 1;
- X mfds[fd1]->fds[0] = fd1;
- X mfds[fd1]->rflag = rflag;
- X } else {
- X if (mfds[fd1]->rflag != rflag) {
- X zerr("file mode mismatch on fd %d",NULL,fd1);
- X return;
- X }
- X if (mfds[fd1]->ct == 1) { /* split the stream */
- X mfds[fd1]->fds[0] = movefd(fd1);
- X mfds[fd1]->fds[1] = movefd(fd2);
- X mpipe(pipes);
- X mfds[fd1]->pipe = pipes[1-rflag];
- X redup(pipes[rflag],fd1);
- X mfds[fd1]->ct = 2;
- X } else /* add another fd to an already split stream */
- X mfds[fd1]->fds[mfds[fd1]->ct++] = movefd(fd2);
- X }
- X}
- X
- Xvoid addvars(l,export) /**/
- XLklist l;int export;
- X{
- Xstruct varasg *v;
- XLklist vl;
- X
- X while (full(l)) {
- X char **arr,**ptr;
- X
- X v = (struct varasg *) ugetnode(l);
- X singsub(&v->name);
- X if (errflag)
- X return;
- X untokenize(v->name);
- X if (v->type == PMFLAG_s) {
- X vl = newlist();
- X addnode(vl,v->str);
- X } else
- X vl = v->arr;
- X prefork(vl);
- X if (errflag)
- X return;
- X postfork(vl,1);
- X if (errflag)
- X return;
- X if (v->type == PMFLAG_s && (!full(vl) || !nextnode(firstnode(vl)))) {
- X Param pm;
- X char *val;
- X
- X if (!full(vl))
- X pm = setsparam(v->name,val = ztrdup(""));
- X else {
- X untokenize(peekfirst(vl));
- X pm = setsparam(v->name,val = ztrdup(ugetnode(vl)));
- X }
- X if (export && !(pm->flags & PMFLAG_x))
- X addenv(v->name,val);
- X continue;
- X }
- X ptr = arr = (char **) zalloc(sizeof(char **)*(countnodes(vl)+1));
- X while (full(vl)) {
- X char *pp;
- X pp = ugetnode(vl);
- X if (*pp) {
- X *ptr = ztrdup(pp);
- X untokenize(*ptr++);
- X }
- X }
- X *ptr = NULL;
- X setaparam(v->name,arr);
- X }
- X}
- X
- Xvoid execcmd(cmd,input,output,bkg,last1) /**/
- XCmd cmd;int input;int output;int bkg;int last1;
- X{
- Xint type;
- Xlong pid = 0;
- Xint save[10],t0;
- Xstruct redir *fn;
- Xstruct multio *mfds[10];
- Xint fil,forked = 0,iscursh = 0,nullexec = 0;
- Xchar *text;
- X
- X args = cmd->args;
- X cn = NULL;
- X for (t0 = 0; t0 != 10; t0++) {
- X save[t0] = 0;
- X mfds[t0] = NULL;
- X }
- X if ((type = cmd->type) == SIMPLE && !full(args))
- X if (full(cmd->redir))
- X if (cmd->flags & CFLAG_EXEC) {
- X nullexec = 1;
- X } else if (!*nullcmd) {
- X zerr("redirection with no command",NULL,0);
- X errflag = lastval = 1;
- X return;
- X } else if (*readnullcmd &&
- X ((Redir)peekfirst(cmd->redir))->type == READ &&
- X !nextnode(firstnode(cmd->redir))) {
- X addnode(args,strdup(readnullcmd));
- X } else
- X addnode(args,strdup(nullcmd));
- X else {
- X addvars(cmd->vars,0);
- X return;
- X }
- X if (full(args) && *(char *) peekfirst(args) == '%') {
- X insnode(args,(Lknode) args,strdup((bkg) ? "bg" : "fg"));
- X bkg = 0;
- X }
- X if (isset(AUTORESUME) && !bkg && !full(cmd->redir) && full(args) &&
- X !input && type == SIMPLE && !nextnode(firstnode(args))) {
- X if (unset(NOTIFY)) scanjobs();
- X if (findjobnam(peekfirst(args)) != -1)
- X pushnode(args,strdup("fg"));
- X }
- X if (unset(RMSTARSILENT) && interact && isset(SHINSTDIN) &&
- X type == SIMPLE && full(args) && nextnode(firstnode(args)) &&
- X !strcmp(peekfirst(args),"rm")) {
- X char *s = getdata(nextnode(firstnode(args)));
- X int l = strlen(s);
- X
- X if (s[0] == Star && !s[1])
- X checkrmall(pwd);
- X else if (l > 2 && s[l-2] == '/' && s[l-1] == Star) {
- X char t = s[l-2];
- X s[l-2] = 0;
- X checkrmall(s);
- X s[l-2] = t;
- X }
- X }
- X if (jobbing) { /* get the text associated with this command */
- X char *s;
- X s = text = getjobtext((vptr) cmd);
- X } else text = NULL;
- X prefork(args); /* do prefork substitutions */
- X if (errflag) {
- X lastval = 1;
- X return;
- X }
- X if (full(args) && ((char*)peekfirst(args))[0] == Inbrack &&
- X ((char*)peekfirst(args))[1] == '\0')
- X ((char*)peekfirst(args))[0] = '[';
- X if (type == SIMPLE && full(args) && !(cmd->flags & CFLAG_COMMAND)) {
- X char *s,*t;
- X cn = (Cmdnam) gethnode(t = s = peekfirst(args),cmdnamtab);
- X if (!cn && isset(HASHCMDS) && strcmp(t,"..")) {
- X while (*t && *t != '/') t++;
- X if (!*t) hashcmd(s,pathchecked);
- X }
- X }
- X if (type == SIMPLE && !cn && isset(AUTOCD) && isset(SHINSTDIN) &&
- X full(args) && !full(cmd->redir) &&
- X !nextnode(firstnode(args)) && cancd(peekfirst(args))) {
- X pushnode(args,strdup("cd"));
- X cn = (Cmdnam) gethnode("cd",cmdnamtab);
- X }
- X
- X /* this is nonzero if cmd is a current shell procedure */
- X
- X iscursh = (type >= CURSH) || (type == SIMPLE && cn &&
- X (cn->type == BUILTIN || cn->type == SHFUNC));
- X
- X /* if this command is backgrounded or (this is an external
- X command and we are not exec'ing it) or this is a builtin
- X with output piped somewhere, then fork. If this is the
- X last stage in a subshell pipeline, don't fork, but make
- X the rest of the function think we forked. */
- X
- X if (bkg || !(iscursh || (cmd->flags & CFLAG_EXEC)) ||
- X (cn && (cn->type == BUILTIN || cn->type == SHFUNC) && output)) {
- X int synch[2];
- X
- X pipe(synch);
- X pid = (last1 && execok()) ? 0 : phork();
- X if (pid == -1) {
- X close(synch[0]);
- X close(synch[1]);
- X return;
- X }
- X if (pid) {
- X close(synch[1]);
- X read(synch[0],"foo",1);
- X close(synch[0]);
- X if (pid == -1)
- X zerr("%e",NULL,errno);
- X else {
- X if (bkg) lastpid = pid;
- X ( void ) addproc(pid,text);
- X }
- X return;
- X }
- X close(synch[0]);
- X entersubsh(bkg);
- X close(synch[1]);
- X forked = 1;
- X }
- X if (bkg && isset(BGNICE))
- X nice(5);
- X
- X /* perform postfork substitutions */
- X postfork(args,!(cmd->flags & CFLAG_NOGLOB));
- X if (errflag) {
- X lastval = 1;
- X goto err;
- X } else {
- X char *s;
- X while (full(args) && (s = peekfirst(args)) && !*s) ugetnode(args);
- X }
- X
- X if (input) /* add pipeline input/output to mnodes */
- X addfd(forked,save,mfds,0,input,0);
- X if (output)
- X addfd(forked,save,mfds,1,output,1);
- X spawnpipes(cmd->redir); /* do process substitutions */
- X while (full(cmd->redir))
- X if ((fn = (struct redir*) ugetnode(cmd->redir))->type == INPIPE) {
- X if (fn->fd2 == -1)
- X execerr();
- X addfd(forked,save,mfds,fn->fd1,fn->fd2,0);
- X } else if (fn->type == OUTPIPE) {
- X if (fn->fd2 == -1)
- X execerr();
- X addfd(forked,save,mfds,fn->fd1,fn->fd2,1);
- X } else {
- X if (!(fn->type == HERESTR || fn->type == CLOSE || fn->type ==
- X MERGE || fn->type == MERGEOUT))
- X if (xpandredir(fn,cmd->redir))
- X continue;
- X if (errflag) execerr();
- X if (fn->type == HERESTR) {
- X fil = getherestr(fn);
- X if (fil == -1) {
- X if (errno != EINTR)
- X zerr("%e",NULL,errno);
- X execerr();
- X }
- X addfd(forked,save,mfds,fn->fd1,fil,0);
- X } else if (fn->type == READ) {
- X fil = open(fn->name,O_RDONLY);
- X if (fil == -1) {
- X if (errno != EINTR)
- X zerr("%e: %s",fn->name,errno);
- X execerr();
- X }
- X addfd(forked,save,mfds,fn->fd1,fil,0);
- X } else if (fn->type == CLOSE) {
- X if (!forked && fn->fd1 < 10)
- X save[fn->fd1] = movefd(fn->fd1);
- X closemn(mfds,fn->fd1);
- X close(fn->fd1);
- X } else if (fn->type == MERGE || fn->type == MERGEOUT) {
- X if (fn->fd2 == FD_COPROC)
- X fn->fd2 = (fn->type == MERGEOUT) ? coprocout : coprocin;
- X if (!forked && fn->fd1 < 10)
- X save[fn->fd1] = movefd(fn->fd1);
- X closemn(mfds,fn->fd1);
- X fil = dup(fn->fd2);
- X addfd(forked,save,mfds,fn->fd1,fil,fn->type == MERGEOUT);
- X } else {
- X if (fn->type >= APP)
- X fil = open(fn->name,
- X (isset(NOCLOBBER) && !(fn->type & 1)) ?
- X O_WRONLY|O_APPEND : O_WRONLY|O_APPEND|O_CREAT,0666);
- X else
- X fil = open(fn->name,dontclob(fn) ?
- X O_WRONLY|O_CREAT|O_EXCL : O_WRONLY|O_CREAT|O_TRUNC,0666);
- X if (fil == -1) {
- X if (errno != EINTR)
- X zerr("%e: %s",fn->name,errno);
- X execerr();
- X }
- X addfd(forked,save,mfds,fn->fd1,fil,1);
- X }
- X }
- X
- X /* we are done with redirection. close the mnodes, spawning
- X tee/cat processes as necessary. */
- X for (t0 = 0; t0 != 10; t0++)
- X closemn(mfds,t0);
- X
- X if (nullexec)
- X return;
- X if (unset(NOEXEC))
- X if (type >= CURSH)
- X {
- X static int (*func[]) DCLPROTO((Cmd)) = {
- X execcursh,exectime,execfuncdef,execfor,execwhile,
- X execrepeat,execif,execcase,execselect,execcond };
- X
- X fixcline(args);
- X lastval = (func[type-CURSH])(cmd);
- X }
- X else if (iscursh) /* builtin or shell function */
- X {
- X if (cmd->vars)
- X addvars(cmd->vars,0);
- X fixcline(args);
- X if (cn && cn->type == SHFUNC)
- X execshfunc(cmd,cn);
- X else
- X {
- X if (forked) closem();
- X lastval = execbin(args,cn);
- X if (isset(PRINTEXITVALUE) && isset(SHINSTDIN) &&
- X lastval && !subsh) {
- X fprintf(stderr,"zsh: exit %d\n",lastval);
- X }
- X fflush(stdout);
- X if (ferror(stdout))
- X {
- X zerr("write error: %e",NULL,errno);
- X clearerr(stdout);
- X }
- X }
- X }
- X else
- X {
- X if (cmd->vars)
- X addvars(cmd->vars,1);
- X if (type == SIMPLE)
- X {
- X closem();
- X execute(cmd->flags & CFLAG_DASH);
- X }
- X else /* ( ... ) */
- X execlist(cmd->u.list);
- X }
- Xerr:
- X if (forked)
- X _exit(lastval);
- X fixfds(save);
- X}
- X
- X/* restore fds after redirecting a builtin */
- X
- Xvoid fixfds(save) /**/
- Xint *save;
- X{
- Xint t0;
- X
- X for (t0 = 0; t0 != 10; t0++)
- X if (save[t0])
- X redup(save[t0],t0);
- X}
- X
- Xvoid entersubsh(bkg) /**/
- Xint bkg;
- X{
- X if (!jobbing)
- X {
- X if (bkg && isatty(0))
- X {
- X close(0);
- X if (open("/dev/null",O_RDWR))
- X {
- X zerr("can't open /dev/null: %e",NULL,errno);
- X _exit(1);
- X }
- X }
- X }
- X else if (!jobtab[thisjob].gleader)
- X {
- X jobtab[thisjob].gleader = getpid();
- X setpgrp(0L,jobtab[thisjob].gleader);
- X if (!bkg)
- X attachtty(jobtab[thisjob].gleader);
- X }
- X else
- X setpgrp(0L,jobtab[thisjob].gleader);
- X subsh = 1;
- X if (SHTTY != -1)
- X {
- X close(SHTTY);
- X SHTTY = -1;
- X }
- X if (jobbing)
- X {
- X signal(SIGTTOU,SIG_DFL);
- X signal(SIGTTIN,SIG_DFL);
- X signal(SIGTSTP,SIG_DFL);
- X signal(SIGPIPE,SIG_DFL);
- X }
- X if (interact)
- X {
- X signal(SIGTERM,SIG_DFL);
- X if (sigtrapped[SIGINT])
- X signal(SIGINT,SIG_IGN);
- X }
- X if (!sigtrapped[SIGQUIT])
- X signal(SIGQUIT,SIG_DFL);
- X opts[MONITOR] = OPT_UNSET;
- X clearjobtab();
- X}
- X
- X/* close all internal shell fds */
- X
- Xvoid closem() /**/
- X{
- Xint t0;
- X
- X for (t0 = 10; t0 != NOFILE; t0++)
- X close(t0);
- X}
- X
- X/* convert here document into a here string */
- X
- Xchar *gethere(str,typ) /**/
- Xchar *str;int typ;
- X{
- Xchar pbuf[256];
- Xint qt = 0,siz = 0,l,strip = 0;
- Xchar *s,*t,*bptr;
- X
- X for (s = str; *s; s++)
- X if (*s == Nularg)
- X qt = 1;
- X untokenize(str);
- X if (typ == HEREDOCDASH)
- X {
- X strip = 1;
- X while (*str == '\t')
- X str++;
- X }
- X t = ztrdup("");
- X for(;;)
- X {
- X char *u,*v;
- X
- X if (!hgets(pbuf,256))
- X break;
- X bptr = pbuf;
- X if (strip)
- X while (*bptr == '\t')
- X bptr++;
- X for (u = bptr, v = str; *u != '\n' && *v; u++,v++)
- X if (*u != *v)
- X break;
- X if (!(*u == '\n' && !*v))
- X {
- X l = strlen(bptr);
- X if (!qt && l > 1 && bptr[l-1] == '\n' && bptr[l-2] == '\\')
- X bptr[l -= 2] = '\0';
- X t = realloc(t,siz+l+1);
- X strncpy(t+siz,bptr,l);
- X siz += l;
- X }
- X else
- X break;
- X }
- X t[siz] = '\0';
- X if (siz && t[siz-1] == '\n')
- X t[siz-1] = '\0';
- X if (!qt)
- X for (s = t; *s; s++)
- X if (*s == '$') {
- X *s = Qstring;
- X } else if (*s == '`') {
- X *s = Qtick;
- X } else if (*s == '(') {
- X *s = Inpar;
- X } else if (*s == ')') {
- X *s = Outpar;
- X } else if (*s == '\\' &&
- X (s[1] == '$' || s[1] == '`')) chuck(s);
- X s = strdup(t);
- X free(t);
- X return s;
- X}
- X
- X/* open here string fd */
- X
- Xint getherestr(fn) /**/
- Xstruct redir *fn;
- X{
- XLklist fake;
- Xchar *s = gettemp(),*t;
- Xint fd;
- X
- X fake = newlist();
- X addnode(fake,fn->name);
- X prefork(fake);
- X if (!errflag)
- X postfork(fake,1);
- X if (errflag)
- X return -1;
- X if ((fd = open(s,O_CREAT|O_WRONLY,0600)) == -1)
- X return -1;
- X while (t = ugetnode(fake))
- X {
- X untokenize(t);
- X write(fd,t,strlen(t));
- X if (full(fake))
- X write(fd," ",1);
- X }
- X write(fd,"\n",1);
- X close(fd);
- X fd = open(s,O_RDONLY);
- X unlink(s);
- X return fd;
- X}
- X
- Xvoid catproc(mn) /**/
- Xstruct multio *mn;
- X{
- Xint len,t0;
- Xchar *buf;
- X
- X if (phork())
- X {
- X for (t0 = 0; t0 != mn->ct; t0++)
- X close(mn->fds[t0]);
- X close(mn->pipe);
- X return;
- X }
- X closeallelse(mn);
- X buf = zalloc(4096);
- X for (t0 = 0; t0 != mn->ct; t0++)
- X while (len = read(mn->fds[t0],buf,4096))
- X write(mn->pipe,buf,len);
- X _exit(0);
- X}
- X
- Xvoid teeproc(mn) /**/
- Xstruct multio *mn;
- X{
- Xint len,t0;
- Xchar *buf;
- X
- X if (phork())
- X {
- X for (t0 = 0; t0 != mn->ct; t0++)
- X close(mn->fds[t0]);
- X close(mn->pipe);
- X return;
- X }
- X buf = zalloc(4096);
- X closeallelse(mn);
- X while ((len = read(mn->pipe,buf,4096)) > 0)
- X for (t0 = 0; t0 != mn->ct; t0++)
- X write(mn->fds[t0],buf,len);
- X _exit(0);
- X}
- X
- Xvoid closeallelse(mn) /**/
- Xstruct multio *mn;
- X{
- Xint t0,t1;
- X
- X for (t0 = 0; t0 != NOFILE; t0++)
- X if (mn->pipe != t0)
- X {
- X for (t1 = 0; t1 != mn->ct; t1++)
- X if (mn->fds[t1] == t0)
- X break;
- X if (t1 == mn->ct)
- X close(t0);
- X }
- X}
- X
- Xlong int zstrtol(s,t,base) /**/
- Xchar *s;char **t;int base;
- X{
- Xint ret = 0;
- X
- X if (base <= 10)
- X for (; *s >= '0' && *s < ('0'+base); s++)
- X ret = ret*base+*s-'0';
- X else
- X for (; idigit(*s) || (*s >= 'a' && *s < ('a'+base-10))
- X || (*s >= 'A' && *s < ('A'+base-10)); s++)
- X ret = ret*base+(idigit(*s) ? (*s-'0') : (*s & 0x1f)+9);
- X if (t)
- X *t = (char *) s;
- X return ret;
- X}
- X
- X/* $(...) */
- X
- XLklist getoutput(cmd,qt) /**/
- Xchar *cmd;int qt;
- X{
- XList list;
- Xint pipes[2];
- X
- X if (*cmd == '<') {
- X int stream;
- X char *fi,*s,x;
- X
- X for (cmd++; *cmd == ' '; cmd++);
- X for (s = cmd; *s && *s != ' '; s++)
- X if (*s == '\\') s++;
- X else if (*s == '$') *s = String;
- X x = *s;
- X *s = '\0';
- X fi = strdup(cmd);
- X *s = x;
- X if (*fi == '~')
- X *fi = Tilde;
- X else if (*fi == '=')
- X *fi = Equals;
- X singsub(&fi);
- X if (errflag)
- X return NULL;
- X stream = open(fi,O_RDONLY);
- X if (stream == -1) {
- X zerr("%e: %s",fi,errno);
- X return NULL;
- X }
- X return readoutput(stream,qt);
- X }
- X if (!(list = parselstring(cmd)))
- X return NULL;
- X mpipe(pipes);
- X if (phork())
- X {
- X popheap();
- X close(pipes[1]);
- X /* chldsuspend(); */
- X return readoutput(pipes[0],qt);
- X }
- X subsh = 1;
- X close(pipes[0]);
- X redup(pipes[1],1);
- X entersubsh(0);
- X signal(SIGTSTP,SIG_IGN);
- X exiting = 1;
- X execlist(list);
- X close(1);
- X exit(0); return NULL;
- X}
- X
- X/* read output of command substitution */
- X
- XLklist readoutput(in,qt) /**/
- Xint in;int qt;
- X{
- XLklist ret;
- Xchar *buf,*ptr;
- Xint bsiz,c,cnt = 0;
- XFILE *fin;
- X
- X fin = fdopen(in,"r");
- X ret = newlist();
- X ptr = buf = ncalloc(bsiz = 64);
- X while ((c = fgetc(fin)) != EOF)
- X if (!qt && isep(c)) {
- X if (cnt) {
- X *ptr = '\0';
- X addnode(ret,buf);
- X ptr = buf = ncalloc(bsiz = 64);
- X cnt = 0;
- SHAR_EOF
- true || echo 'restore of zsh2.2/src/exec.c failed'
- fi
- echo 'End of zsh2.2 part 7'
- echo 'File zsh2.2/src/exec.c is continued in part 8'
- echo 8 > _shar_seq_.tmp
- exit 0
-
- exit 0 # Just in case...
-